﻿#include "../../includes/multimedia/czipmanager.h"
#include "../../includes/QsLog/QsLog.h"
#include "../../includes/common/common.h"

#include <QFileInfo>
#include <QDir>
#include <QDebug>
#include <QCoreApplication>

CZipManager::CZipManager(QObject *parent)
    : QObject(parent)
{

}

CZipManager::~CZipManager(void)
{

}

/**
 * 得到指定目录下所有的文件
 *
 * @param _filePath 要得到文件的目录
 * @param filelist 用于存放读取到的文件
 * @return 如果文件读取成功返回0，否则返回-1
 */
int CZipManager::FindFile(const QString& _filePath,QVector<QString> &filelist)
{
    QDir dir(_filePath);

    if (!dir.exists()) {
        return -1;
    }

    //取到所有的文件和文件名，但是去掉.和..的文件夹（这是QT默认有的）
    dir.setFilter(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot);

    //文件夹优先
    dir.setSorting(QDir::DirsFirst);

    //转化成一个list
    QFileInfoList list = dir.entryInfoList();
    //QStringList infolist = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
    if(list.size()< 1 ) {
        return -1;
    }
    int i=0;

    //递归算法的核心部分
    do{
        QFileInfo fileInfo = list.at(i);
        //如果是文件夹，递归
        bool bisDir = fileInfo.isDir();
        if(bisDir) {
            FindFile(fileInfo.filePath(),filelist);
        }
        else{
            filelist.push_back(list[i].absoluteFilePath());
        }//end else
        i++;
    } while(i < list.size());

    return 0;
}

/**
 * @brief CZipManager::unzipFile 解压指定压缩文件到指定目录
 * @param srcZipFile 要解压的文件
 * @param decCatalogue 解压到的目录
 * @return 如果文件解压成功返回真，否则返回假
 */
bool CZipManager::unzipFile(QString srcZipFile,QString decCatalogue)
{
    QFileInfo pFileInfo(srcZipFile);
    if(!pFileInfo.exists())
        return false;

    QFileInfo pdecCatalogue(decCatalogue);
    if(!pdecCatalogue.exists())
    {
        QDir pdecDir(decCatalogue);
        if(!pdecDir.exists())
            pdecDir.mkdir(decCatalogue);
    }

    QZipReader pZipReader(srcZipFile);
    if(!pZipReader.exists())
        return false;

    QVector<QZipReader::FileInfo> pFileInfos = pZipReader.fileInfoList();
    if(pFileInfos.isEmpty())
        return false;

    QLOG_INFO()<<"unzipFile start path:"<<decCatalogue;

    for(int i=0;i<pFileInfos.size();i++)
    {
        QString pFilePath = decCatalogue + "/" + pFileInfos[i].filePath;

        int pos = pFilePath.lastIndexOf("/");
        if(pos > 0)
        {
            QString pTempDir = pFilePath.mid(0,pos);

            QDir pNewDir(pTempDir);
            if(!pNewDir.exists())
                pNewDir.mkpath(pTempDir);
        }

        QFile pFile(pFilePath);
        if(pFile.open(QIODevice::WriteOnly))
        {
            pFile.write(pZipReader.fileData(pFileInfos[i].filePath));
            pFile.close();

            QLOG_INFO()<<"unzipFile file:"<<pFilePath;
            emit processProcessingprogress(1,i,pFileInfos.size(),pFilePath);
        }

        QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
    }

    pZipReader.close();

    QLOG_INFO()<<"unzipFile finished file count:"<<pFileInfos.size();

    return true;
}

/**
 * @brief zipFile 压缩指定文件或者文件夹到指定压缩文件中
 * @param filepath 要压缩的文件，可以是文件，也可以是文件夹
 * @param decZipFile 输出的压缩文件
 * @return 如果文件压缩成功返回真，否则返回假
 */
bool CZipManager::zipFile(QString filepath,QString decZipFile)
{
    if(filepath.isEmpty() || decZipFile.isEmpty())
        return false;

    QFileInfo pFileInfo(filepath);
    if(!pFileInfo.exists())
        return false;

    QString rootPath;
    QVector<QString> listFilePaths;

    // 判断是文件还是文件夹
    if(pFileInfo.isDir())
    {
        rootPath = pFileInfo.absoluteFilePath();

        FindFile(rootPath,listFilePaths);
    }
    else
    {
        int findPos = pFileInfo.absoluteFilePath().lastIndexOf("/");
        rootPath = pFileInfo.absoluteFilePath().mid(0,findPos);

        listFilePaths.push_back(pFileInfo.absoluteFilePath());
    }

    // 没有找到文件
    if(listFilePaths.isEmpty())
        return false;

    // 开始压缩文件
    QZipWriter pZipWriter(decZipFile);
    if(!pZipWriter.exists())
        return false;

    QLOG_INFO()<<"zipFile start path:"<<decZipFile;

    for(int i=0;i<listFilePaths.size();i++)
    {
        QFile pFile(listFilePaths[i]);
        if(!pFile.exists())
            continue;

        if(pFile.open(QIODevice::ReadOnly))
        {
            QString pTempFilePath = listFilePaths[i];
            int pos = pTempFilePath.lastIndexOf(rootPath)+rootPath.size()+1;
            pTempFilePath = pTempFilePath.mid(pos,pTempFilePath.size()-pos);

            pZipWriter.addFile(pTempFilePath,pFile.readAll());

            QLOG_INFO()<<"zipFile file:"<<listFilePaths[i];
            emit processProcessingprogress(0,i,listFilePaths.size(),listFilePaths[i]);

            pFile.close();
        }

        QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
    }

    QLOG_INFO()<<"zipFile finished file count:"<<listFilePaths.size();

    pZipWriter.close();

    return true;
}
